//#include "gd32f1x0.h"
#include "aoi.h"
#include "bb.h"
#include "bb_i2c_master.h"
#include "bsp.h"
#include "gd32f1x0.h"
#include "memory.h"
#include "plantform_systick.h"

extern struct LCD lcd;

void _nop_(void)
{
	delay_us(2);
}

void delay_ss(uint32_t n)
{
	delay_ms(n * 1000);
}

void lcd_sck(int v)
{
	bsp_setPin(19, v);
}

void lcd_sda(int v)
{
	bsp_setPin(18, v);
}

void lcd_cd(int v)
{
	bsp_setPin(17, v);
}

void lcd_cs(int v)
{
	bsp_setPin(16, v);
}

void lcd_res(int v)
{
	bsp_setPin(15, v);
}

/***************************************************


		port from origin project


***************************************************/
/*
void lcd_image(unsigned char *p)
{
	unsigned char i;
	for (i = 0; i < 19; i++) {
		sendbyte(*p++);
	}
}*/

const unsigned char pic1[] =
    {
	0x00, 0x00, 0x00, 0x00, 0x92,
	0x92, 0x92, 0x92, 0x92, 0x92,
	0xb5, 0xaf, 0x8b, 0x29, 0x4a,
	0x92, 0x92, 0x92, 0x92, 0x92,
	0x9a, 0x92, 0x98, 0x59};

const unsigned char pic2[] =
    {
	0x00, 0x00, 0x00, 0x00, 0x65,
	0x65, 0x65, 0x65, 0x65, 0x6d,
	0x34, 0xc4, 0xea, 0xf4, 0xb5,
	0x65, 0x6d, 0x65, 0x6d, 0x65,
	0x65, 0x6d, 0x65, 0x22};

const unsigned char pic3[] =
    {
	0x00, 0x00, 0x00, 0x00, 0x4c,
	0x4c, 0x4c, 0x4c, 0x4c, 0x4c,
	0xca, 0x32, 0x60, 0x4b, 0xc4,
	0x4c, 0x44, 0x4c, 0x44, 0x4c,
	0x44, 0x4c, 0x42, 0x1c};

/***************************************************


		external functions implement


***************************************************/
#include "bb_i2c_master.h"

struct bb_i2c_master_initial_typedef bb_init;

struct bb_i2c_master i2c;

void lcm_reset(void)
{
}

#define _I2C_SDA_PORT GPIOB
#define _I2C_SDA_Pin GPIO_PIN_7

#define _I2C_SCL_PORT GPIOB
#define _I2C_SCL_Pin GPIO_PIN_6

static uint8_t _i2c_sda_get(void)
{
	// uint8_t r = gpio_output_bit_get(_I2C_SDA_PORT, _I2C_SDA_Pin);
	uint8_t r = gpio_input_bit_get(_I2C_SDA_PORT, _I2C_SDA_Pin);
	if (r == RESET) {
		return 0;
	} else {
		return 1;
	}
}

static uint8_t _i2c_scl_get(void)
{
	// uint8_t r = gpio_output_bit_get(_I2C_SCL_PORT, _I2C_SCL_Pin);
	uint8_t r = gpio_input_bit_get(_I2C_SCL_PORT, _I2C_SCL_Pin);
	if (r == RESET) {
		return 0;
	} else {
		return 1;
	}
}

static void _i2c_sda_set(uint8_t state)
{
	// state ? (gpio_bit_set(_I2C_SDA_PORT, _I2C_SDA_Pin)) : (gpio_bit_reset(_I2C_SDA_PORT, _I2C_SDA_Pin));
	if (state) {
		gpio_bit_set(_I2C_SDA_PORT, _I2C_SDA_Pin);
	} else {
		gpio_bit_reset(_I2C_SDA_PORT, _I2C_SDA_Pin);
	}
}

static void _i2c_scl_set(uint8_t state)
{
	// state ? (gpio_bit_set(_I2C_SDA_PORT, _I2C_SDA_Pin)) : (gpio_bit_reset(_I2C_SDA_PORT, _I2C_SDA_Pin));
	if (state) {
		gpio_bit_set(_I2C_SCL_PORT, _I2C_SCL_Pin);
	} else {
		gpio_bit_reset(_I2C_SCL_PORT, _I2C_SCL_Pin);
	}
}

uint8_t reg[32];
uint8_t buffer[32];
uint8_t addr_w = 0x7C;
#define d_off 2
#define d_len 20
#define p_size (d_off + d_len)

static void lcm_io_initial(void)
{
	// IO initial
	gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);
	gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_10MHZ, GPIO_PIN_6);

	gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
	gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_10MHZ, GPIO_PIN_7);
}

static void lcm_initial(void)
{
	bb_init._delay_us = delay_us;
	bb_init.speed = 100000;
	bb_init.scl_get = _i2c_scl_get;
	bb_init.sda_get = _i2c_sda_get;
	bb_init.scl_set = _i2c_scl_set;
	bb_init.sda_set = _i2c_sda_set;

	// i2c initial
	bb_i2c_master_initial(&i2c, &bb_init);

	uint8_t init_code[] = {
	    0x80,
	    0xA2,
	    0xc8,
	    0xe4,
	    0xe8,
	    0xf0,
	    0xf8,
	};

	for (int i = 0; i < sizeof(init_code); i++) {
		uint8_t r = init_code[i];
		bb_i2c_master_send(&i2c, addr_w, &r, 1);
	}
}

static void data_pack(uint8_t *pack, uint8_t *dat)
{
	pack[0] = 0xe8;
	pack[1] = 0x00;

	memcpy(pack + 2, dat, 20);
}

static void fill_with_byte(uint8_t *pack, uint8_t B)
{
	pack[0] = 0xe8;
	pack[1] = 0x00;

	for (uint8_t i = 2; i < 24+2; i++) {
		pack[i] = B;
	}
}

static void lcm_full(void)
{
	fill_with_byte(reg, 0xFF);
	bb_i2c_master_send(&i2c, addr_w, reg, 24+2);
}

static void lcm_clear(void)
{
	fill_with_byte(reg, 0x00);
	bb_i2c_master_send(&i2c, addr_w, reg, 24+2);
}

static void lcm_row_even(void)
{
	fill_with_byte(reg, 0xAA);
	bb_i2c_master_send(&i2c, addr_w, reg, 24+2);
}

static void lcm_row_odd(void)
{
	fill_with_byte(reg, 0x55);
	bb_i2c_master_send(&i2c, addr_w, reg, 24+2);
}

static void lcm_column_odd(void)
{
	fill_with_byte(reg, 0xF0);
	bb_i2c_master_send(&i2c, addr_w, reg, 24+2);
}

static void lcm_column_even(void)
{
	fill_with_byte(reg, 0x0F);
	bb_i2c_master_send(&i2c, addr_w, reg, 24+2);
}

static void lcm_main(void)
{
}

void aoi_config(void)
{
	lcd.io_initial = lcm_io_initial;
	lcd.test = lcm_main;
	lcd.reset = lcm_reset;
	lcd.initial = lcm_initial;
	lcd.screen[0] = lcm_clear;
	lcd.screen[1] = lcm_column_even;
	lcd.screen[2] = lcm_column_odd;
	lcd.screen[3] = lcm_row_even;
	lcd.screen[4] = lcm_row_odd;
	lcd.screen[0xf] = lcm_full;
}
